package com.demon.auto.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demon.auto.dao.SignClientDao;
import com.demon.auto.model.dto.SignClientDto;
import com.demon.auto.model.entity.SignClientEntity;
import com.demon.auto.model.entity.UserClientRelationEntity;
import com.demon.auto.model.vo.PageVo;
import com.demon.auto.model.vo.SignClientVo;
import com.demon.auto.service.SignClientService;
import com.demon.auto.service.UserClientRelationService;
import com.demon.auto.utils.ObjectDeepCompareUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 签到客户端
 *
 * @version 1.0
 * @author huangrz
 * @date 2025/02/13 17:08
 */
@Slf4j
@Service
public class SignClientServiceImpl extends ServiceImpl<SignClientDao, SignClientEntity> implements SignClientService {

    @Autowired
    private UserClientRelationService userClientRelationService;

    @Override
    public Boolean updateOnlineTime(String clientName, LocalDateTime localDateTime) {
        if (StringUtils.isBlank(clientName)) {
            log.error("[updateOnlineTime] 客户端名称为空!");
            return false;
        }
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        LambdaUpdateWrapper<SignClientEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(SignClientEntity::getClientName, clientName)
                .set(SignClientEntity::getLastOnlineTime, localDateTime)
                .set(SignClientEntity::getUpdateTime, localDateTime);
        return update(updateWrapper);
    }

    @Override
    public List<SignClientDto> getAllOpenSignClientList() {
        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SignClientEntity::getValidFlag, true)
                .eq(SignClientEntity::getOpenFlag, true);
        List<SignClientEntity> signClientList = list(queryWrapper);
        List<SignClientDto> signClientDtoList = new ArrayList<>();
        for (SignClientEntity client : signClientList) {
            String configJson = client.getConfigJson();
            if (StringUtils.isBlank(configJson)) {
                log.error("客户端配置信息为空！clientName:{}", client.getClientName());
                continue;
            }
            signClientDtoList.add(new SignClientDto(client));
        }
        return signClientDtoList;
    }

    @Override
    public SignClientDto getSignClientByClientName(String clientName) {
        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SignClientEntity::getClientName, clientName)
                .eq(SignClientEntity::getValidFlag, true);
        return new SignClientDto(getOne(queryWrapper, false));
    }

    @Override
    public List<SignClientDto> getUserSignClient(Long userId) {
        List<UserClientRelationEntity> userClientRelationInfo = userClientRelationService.getUserClientRelationInfo(userId);
        if (CollectionUtils.isEmpty(userClientRelationInfo)) {
            return null;
        }

        Map<Long, UserClientRelationEntity> clientIdRelationMap = userClientRelationInfo.stream()
                .collect(Collectors.toMap(UserClientRelationEntity::getClientId, relation -> relation));

        List<Long> clientIds = userClientRelationInfo.stream()
                .map(UserClientRelationEntity::getClientId)
                .distinct()
                .collect(Collectors.toList());

        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SignClientEntity::getValidFlag, true)
                .in(SignClientEntity::getId, clientIds);
        List<SignClientEntity> signClientList = list(queryWrapper);

        if (CollectionUtils.isEmpty(signClientList)) {
            return null;
        }

        return signClientList.stream().map(entity -> {
            SignClientDto dto = new SignClientDto(entity);
            UserClientRelationEntity relationInfo = clientIdRelationMap.getOrDefault(entity.getId(), null);
            if (relationInfo != null) {
                dto.setAlias(relationInfo.getAlias());
                dto.setRelationTime(relationInfo.getCreateTime());
                // 超过2分钟视为离线
                dto.setOnlineFlag(dto.getLastOnlineTime() != null && Math.abs((Duration.between(dto.getLastOnlineTime(), LocalDateTime.now()).toMinutes())) < 2);
            }
            return dto;
        }).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveUserSignClient(SignClientDto signClient) {
        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SignClientEntity::getClientName, signClient.getClientName())
                .eq(SignClientEntity::getValidFlag, true);
        SignClientEntity oldClient = getOne(queryWrapper, false);
        if (oldClient != null) {
            // 客户端名称已存在
            if (!oldClient.getId().equals(signClient.getId())) {
                return null;
            }
            // 判断是否内容改变
            SignClientDto oldSignClient = new SignClientDto(oldClient);
            if (ObjectDeepCompareUtil.isDeepEquals(oldSignClient, signClient,
                    "alias", "lastOnlineTime", "createTime", "updateTime", "onlineFlag", "relationTime")) {
                // 判断别名是否改变
                return userClientRelationService.saveUserClientRelationInfo(signClient.getId(), null, signClient.getAlias());
            }
            return updateById(new SignClientEntity(signClient));
        }

        // 新增
        SignClientEntity newSinClient = new SignClientEntity(signClient);
        if (save(newSinClient)) {
            // 保存关联信息
            return userClientRelationService.saveUserClientRelationInfo(newSinClient.getId(), null, signClient.getAlias());
        }
        return false;
    }

    @Override
    public PageVo<SignClientEntity> queryByPage(SignClientVo condition) {
        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        if (condition.getId() != null) {
            queryWrapper.eq(SignClientEntity::getId, condition.getId());
        }
        if (condition.getValidFlag() != null) {
            queryWrapper.eq(SignClientEntity::getValidFlag, condition.getValidFlag());
        }
        if (StringUtils.isNotBlank(condition.getClientName())) {
            queryWrapper.like(SignClientEntity::getClientName, condition.getClientName());
        }
        if (StringUtils.isNotBlank(condition.getConfigQuery())) {
            queryWrapper.like(SignClientEntity::getConfigJson, condition.getConfigQuery());
        }
        if (condition.getOnlineTimeBegin() != null && condition.getOnlineTimeEnd() != null) {
            queryWrapper.between(SignClientEntity::getLastOnlineTime, condition.getOnlineTimeBegin(), condition.getOnlineTimeEnd());
        }
        if (condition.getCreateTimeBegin() != null && condition.getCreateTimeEnd() != null) {
            queryWrapper.between(SignClientEntity::getCreateTime, condition.getCreateTimeBegin(), condition.getCreateTimeEnd());
        }
        if (condition.getUpdateTimeBegin() != null && condition.getUpdateTimeEnd() != null) {
            queryWrapper.between(SignClientEntity::getUpdateTime, condition.getUpdateTimeBegin(), condition.getUpdateTimeEnd());
        }
        return baseMapper.selectPage(condition, queryWrapper);
    }

    @Override
    public boolean judgeClientNameIsExist(String clientName) {
        LambdaQueryWrapper<SignClientEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SignClientEntity::getClientName, clientName);
        queryWrapper.eq(SignClientEntity::getValidFlag, true);
        return getOne(queryWrapper, false) != null;
    }

    @Override
    public void updateAutoSignTime(String clientName, LocalDateTime autoSignTime) {
        if (StringUtils.isBlank(clientName)) {
            return;
        }
        LambdaUpdateWrapper<SignClientEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(SignClientEntity::getAutoSignTime, autoSignTime)
                .eq(SignClientEntity::getClientName, clientName);
        update(updateWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean invalidUserClient(Long clientId, Long userId) {
        SignClientEntity client = getById(clientId);
        // 非创建人仅删除关联信息
        if (client == null || !userId.equals(client.getCreateCode())) {
            return userClientRelationService.deleteByUserClientId(clientId, userId) > 0;
        }

        // 作废客户端
        if (baseMapper.deleteById(clientId) < 1) {
            log.error("删除客户端异常！clientId: {}", clientId);
            return false;
        }
        // 删除所有关联信息
        return userClientRelationService.deleteUserClientAllRelation(clientId) > 0;
    }

}
